package com.ioc.business.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ioc.business.base.domain.CustomerInfo;
import com.ioc.business.base.mapper.CustomerInfoMapper;
import com.ioc.business.order.domain.ReceiveOrder;
import com.ioc.business.order.domain.bo.receive.ReceiveOrderBo;
import com.ioc.business.order.domain.bo.receive.ReceiveOrderQueryBo;
import com.ioc.business.order.enums.OrderStatusEnum;
import com.ioc.business.order.mapper.ReceiveOrderMapper;
import com.ioc.business.order.service.IReceiveOrderService;
import com.ioc.business.order.vo.receive.ReceiveOrderImportVo;
import com.ioc.business.order.vo.receive.ReceiveOrderPageVo;
import com.ioc.business.order.vo.receive.ReceiveOrderVo;
import com.ioc.common.constant.UserConstants;
import com.ioc.common.core.page.TableVo;
import com.ioc.common.exception.ServiceException;
import com.ioc.common.utils.SecurityUtils;
import com.ioc.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 收货订单表 服务实现类
 * </p>
 *
 * @author WeiZhongRong
 * @since 2025-01-07
 */
@Service
@AllArgsConstructor
public class ReceiveOrderServiceImpl extends ServiceImpl<ReceiveOrderMapper, ReceiveOrder> implements IReceiveOrderService {

    private final CustomerInfoMapper customerInfoMapper;

    @Override
    public TableVo<ReceiveOrder, ReceiveOrderPageVo> selectReceiveOrderPageList(ReceiveOrderQueryBo queryBo) {
        List<ReceiveOrder> result = baseMapper
                .queryPageList(queryBo);
        List<ReceiveOrderPageVo> pageVos = new ArrayList<>(result.size());
        if (CollectionUtil.isNotEmpty(result)) {
            pageVos = buildPageVos(result);
        }
        return new TableVo<>(result, pageVos);
    }

    private List<ReceiveOrderPageVo> buildPageVos(List<ReceiveOrder> records) {
        return records.stream().map(record -> {
            ReceiveOrderPageVo vo = new ReceiveOrderPageVo();
            BeanUtils.copyProperties(record, vo);
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public ReceiveOrderVo selectReceiveOrderById(Long receiveOrderId) {
        ReceiveOrder receiveOrder = getById(receiveOrderId);
        if (ObjectUtil.isNotEmpty(receiveOrder)) {
            ReceiveOrderVo receiveOrderVo = new ReceiveOrderVo();
            BeanUtils.copyProperties(receiveOrder, receiveOrderVo);
            return receiveOrderVo;
        }
        return null;
    }

    /**
     * 新增收货订单
     *
     * @param bo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addReceiveOrder(ReceiveOrderBo bo) {
        ReceiveOrder receiveOrder = new ReceiveOrder();
        BeanUtils.copyProperties(bo, receiveOrder);
        receiveOrder.setCreateBy(SecurityUtils.getUsername());
        receiveOrder.setCreateTime(new Date());
        receiveOrder.setUpdateBy(SecurityUtils.getUsername());
        receiveOrder.setUpdateTime(receiveOrder.getCreateTime());
        receiveOrder.setDelFlag(UserConstants.DEL_FLAG_NORMAL);
        return save(receiveOrder);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateReceiveOrder(ReceiveOrderBo bo) {
        ReceiveOrder receiveOrder = new ReceiveOrder();
        BeanUtils.copyProperties(bo, receiveOrder);
        receiveOrder.setUpdateBy(SecurityUtils.getUsername());
        receiveOrder.setUpdateTime(receiveOrder.getCreateTime());
        return updateById(receiveOrder);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeReceiveOrder(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return false;
        }
        List<ReceiveOrder> updateList = idList.stream().map(id -> {
            ReceiveOrder receiveOrder = new ReceiveOrder();
            receiveOrder.setReceiveOrderId(id);
            receiveOrder.setDelFlag(UserConstants.DEL_FLAG_REMOVED);
            return receiveOrder;
        }).collect(Collectors.toList());
        return updateBatchById(updateList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importReceiveOrder(List<ReceiveOrderImportVo> voList) {
        List<ReceiveOrder> receiveOrderList = verifyImportData(voList);
        saveBatch(receiveOrderList);
    }

    private List<ReceiveOrder> verifyImportData(List<ReceiveOrderImportVo> voList) {
        if (CollectionUtil.isEmpty(voList)) {
            throw new ServiceException("导入数据不能为空");
        }
        List<CustomerInfo> list = new LambdaQueryChainWrapper<>(customerInfoMapper)
                .eq(CustomerInfo::getDelFlag, UserConstants.DEL_FLAG_NORMAL)
                .list();
        Map<String, Long> customerNameIdMapMap = CustomerInfo.toNameIdMap(list);
        List<ReceiveOrder> receiveOrderList = new ArrayList<>(voList.size());
        String username = SecurityUtils.getUsername();
        Date date = new Date();
        for (ReceiveOrderImportVo receiveOrderImportVo : voList) {
            ReceiveOrder receiveOrder = new ReceiveOrder();
            BeanUtils.copyProperties(receiveOrderImportVo, receiveOrder);
            verifyField(receiveOrder, receiveOrderImportVo, customerNameIdMapMap);
            receiveOrder.setCreateBy(username);
            receiveOrder.setCreateTime(date);
            receiveOrder.setUpdateBy(username);
            receiveOrder.setUpdateTime(date);
            receiveOrder.setDelFlag(UserConstants.DEL_FLAG_NORMAL);
            receiveOrderList.add(receiveOrder);
        }
        return receiveOrderList;
    }

    private void verifyField(ReceiveOrder receiveOrder,
                             ReceiveOrderImportVo receiveOrderImportVo,
                             Map<String, Long> customerNameIdMapMap) {
        if (StrUtil.isBlank(receiveOrderImportVo.getOrderCode())) {
            throw new ServiceException("收货单号不能为空!");
        }

        String customerName = receiveOrderImportVo.getCustomerName();
        if (StrUtil.isBlank(customerName)) {
            throw new ServiceException("客户名称不能为空!");
        }
        Long customerId = customerNameIdMapMap.getOrDefault(customerName, null);
        if (ObjectUtil.isEmpty(customerId)) {
            throw new ServiceException("客户名称【" + customerName + "】不存在!");
        }
        receiveOrder.setCustomerId(customerId);
        receiveOrder.setCustomerName(customerName);

        String receiveTimeStr = receiveOrderImportVo.getReceiveTime();
        Date receiveTime = null;
        try {
            receiveTime = StrUtil.isNotBlank(receiveTimeStr) ? DateUtil.parse(receiveTimeStr) : null;
        } catch (Exception e) {
            throw new ServiceException("到货时间格式不正确!");
        }
        receiveOrder.setReceiveTime(receiveTime);

        String estimatedFinishTimeStr = receiveOrderImportVo.getEstimatedFinishTime();
        Date estimatedFinishTime = null;
        try {
            estimatedFinishTime = StrUtil.isNotBlank(estimatedFinishTimeStr) ? DateUtil.parse(estimatedFinishTimeStr) : null;
        } catch (Exception e) {
            throw new ServiceException("预计完成时间格式不正确!");
        }
        receiveOrder.setEstimatedFinishTime(estimatedFinishTime);
        receiveOrder.setTaskProgress(StringUtils.numberStrToPercentStr(receiveOrderImportVo.getTaskProgress()));
        OrderStatusEnum receiveStatus = OrderStatusEnum.NORMAL;
        String receiveStatusStr = receiveOrderImportVo.getReceiveStatus();
        if (StrUtil.isNotBlank(receiveStatusStr)) {
            OrderStatusEnum statusEnum = OrderStatusEnum.getByDesc(receiveStatusStr);
            if (ObjectUtil.isEmpty(statusEnum)) {
                throw new ServiceException("收货状态【" + receiveStatusStr + "】不存在!");
            }
            receiveStatus = statusEnum;
        }
        receiveOrder.setReceiveStatus(receiveStatus);
    }


}
